package com.shen.library_nettysocket.timer

import com.shen.library_nettysocket.IMSConfig
import com.shen.library_nettysocket.interf.IMSClientInterface
import com.shen.library_nettysocket.protobuf.MessageProtobuf
import java.util.*

/**
 * 消息发送超时定时器，每一条消息对应一个定时器
 *
 * [imsClient] ims客户端
 * [msg] 发送的消息
 */
class MsgTimeoutTimer(private val imsClient: IMSClientInterface, private val msg: MessageProtobuf.Msg) : Timer() {

    /** 当前·重发次数 */
    private var currentResendCount = 0
    /** 消息「发送超时」任务 */
    private var task: MsgTimeoutTask?


    init {
        task = MsgTimeoutTask()
        schedule(task, imsClient.resendInterval.toLong(), imsClient.resendInterval.toLong())
    }

    /**
     * 消息发送超时任务
     */
    private inner class MsgTimeoutTask : TimerTask() {
        override fun run() {
            if (imsClient.isClosed) {
                imsClient.msgTimeoutTimerManager?.remove(msg.head.msgId)
                return
            }

            currentResendCount++
            if (currentResendCount > imsClient.resendCount) {
                // 「重发·次数」大于「可重发·次数」，直接标识为「发送失败」，并通过「消息转发器」通知「应用层」
                try {
                    val builder: MessageProtobuf.Msg.Builder = MessageProtobuf.Msg.newBuilder()
                    val headBuilder: MessageProtobuf.Head.Builder = MessageProtobuf.Head.newBuilder()
                    headBuilder.msgId = msg.head.msgId
                    headBuilder.msgType = imsClient.serverSentReportMsgType
                    headBuilder.timestamp = System.currentTimeMillis()
                    headBuilder.statusReport = IMSConfig.DEFAULT_REPORT_SERVER_SEND_MSG_FAILURE
                    builder.head = headBuilder.build()

                    imsClient.msgDispatcher?.receivedMsg(builder.build())           // 通知「应用层」消息「发送失败」

                } finally {
                    imsClient.msgTimeoutTimerManager?.remove(msg.head.msgId)        // 从「消息发送·超时管理器」移除「该消息」
                    imsClient.resetConnect()                                        // 执行到这里，认为连接已断开或不稳定，触发重连
                    currentResendCount = 0
                }

            } else {
                sendMsg()                       // 发送消息，但不再加入超时管理器，达到最大发送失败次数就算了
            }
        }
    }

    fun sendMsg() {
        println("正在重发消息，message=$msg")
        imsClient.sendMsg(msg, false)
    }

    fun getMsg(): MessageProtobuf.Msg {
        return msg
    }

    override fun cancel() {
        if (task != null) {
            task!!.cancel()
            task = null
        }
        super.cancel()
    }

}